/***********************************************************************//**
 *   \file DFT.h		\author belot nicolas (karrakis)           *
 *   \brief define DFT
 *   Manipulation of DFT		                                   *
 ************************************************************************//*
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#ifndef DFT_H
#define DFT_H 1
#include "libtrckr.h"
#include <fftw3.h>
#include "math.h"
#include "Buffer.h"
#include "Utility.h"
namespace libtrckr {
class DFT {
/** \class libtrckr::DFT
    \brief Manipulation of DFTs
	Allow Multiplication and addition of DFTs
*/
	public:
	/** Default Constructor
		Define an empty Discrete Fourier Transform with	1024 complex
	*/
	DFT();
	/** Constructor
		Define an empty DFT with n complex
	\param Size number of complex
	*/
	DFT(unsigned int);
	/** Contructor
		Create an DFT with the real part and the imaginary part of n complex
	\param real reals
	\param img imaginaries
	\param Size number of item
	*/
	DFT(double*,double*, unsigned int);
	/** Copy Contructor
	*/
	DFT(const DFT&);
	/** Constructor
		Create an DFT from an array of complex
	\param data the array of complex
	\param Size number of item
	*/
	DFT(fftw_complex*,unsigned int);
	/** Destructor
	*/
	~DFT();

	//Accessor
	/** Accessor to the Real Part
		return the real part of the DFT
	\return an array of double containing the real part of the DFT
	*/
	double *getRealParts() const;
	uint getRealParts(double*,uint) const;
	uint getRealParts(Buffer&) const;
	/**Accessor to the Imaginary Part
		return the imaginary part of the DFT
	\return an array of double containing the imaginary part of the DFT
	*/
	double *getImaginaryParts() const;
	uint getImaginaryParts(double *,uint) const;
	uint getImaginaryParts(Buffer&) const;
	/**Accessor to the Magnetudes
		return the Magnetudes of the DFT
	\return an array of double containing the magnetudes
	*/
	double *getMagnetudes() const;
	uint getMagnetudes(double *,uint) const;
	uint getMagnetudes(Buffer &)const;
	/** return the size
	\return size of the DFT
	*/
	unsigned int getSize() const;
	void setData(double*, double*,int);
	//operator
	DFT operator=(const DFT&);
	/** Multiplication Operator 
	*/
	DFT operator*(const DFT&);
	/** Multiplication and assign Operator
	*/
	void operator*=(const DFT&);
	/** Addition Operator
	*/
	DFT operator+(const DFT&);
	/** Addition and assign Operator
	*/
	void operator+=(const DFT&);

	/** Cast to Buffer */
	operator Buffer( );
	//protected
	protected :
	/** An accessor to internal representation
		Allow the child class to access to the internal representation of DFT.
		Provide only  to accelerate algorythm
	\return an pointer on the DFT representation
	*/
	fftw_complex* getContent() const;

	private :
		/** resize a part of a dft
			resize part1 or part2 to the biggest of the both with the Utility::Interpolate function
		\param part1 an array of double
		\param size1 size of part1
		\param part2 an array of double
		\param size2 size of part2
		\return an interpolate array of double 
		*/
		double *resize(double*, unsigned int, double*, unsigned int);
		/** Multiply arrays of complex
		\param re1 array containing the real parts of the first array of complex
		\param im1 array containing the imaginary parts of the first array of complex
		\param re2 array containing the real parts of the second array of complex
		\param im2 array containing the imaginary parts of the second array of complex
		\param size size of the arrays
		*/
		fftw_complex* multiply(double*,double*,double*,double*,unsigned int );
		/** add arrays of complex
		\param re1 array containing the real parts of the first array of complex
		\param im1 array containing the imaginary parts of the first array of complex
		\param re2 array containing the real parts of the second array of complex
		\param im2 array containing the imaginary parts of the second array of complex
		\param size size of the arrays
		*/
		fftw_complex* add(double*,double*,double*,double*,unsigned int );
		/** array of complex
		*/
		fftw_complex* dft;
		/** size of the array
		*/
		unsigned int size;

};
}
#endif


